package com.itheima.movement.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.itheima.common.Base64Util;
import com.itheima.common.ThreadLocalUtil;
import com.itheima.api.UserClient;
import com.itheima.common.TimeUtil;
import com.itheima.entity.dto.MovementDto;
import com.itheima.entity.dto.UploadDto;
import com.itheima.entity.dto.UserClientDto;
import com.itheima.entity.pojo.Movement;
import com.itheima.entity.pojo.MovementComment;
import com.itheima.entity.pojo.MovementLike;
import com.itheima.entity.vo.*;
import com.itheima.movement.mapper.MovementLikeMapper;
import com.itheima.movement.mapper.MovementMapper;
import com.itheima.movement.service.MovementCommentService;
import com.itheima.movement.service.MovementLikeService;
import com.itheima.movement.service.MovementService;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author :wujunjie
 * createTime :2022-12-22 15:42
 * description :
 */
@Service
public class MovementServiceImpl implements MovementService {
    @Autowired
    private MovementMapper movementMapper;
    @Autowired
    private UserClient userClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private MovementLikeService movementLikeService;
    @Autowired
    private MovementCommentService movementCommentService;

    @Override
    public Boolean insertMovement(MovementDto movementDto) throws Exception {
        Movement movement = new Movement();
        BeanUtils.copyProperties(movementDto, movement);
        List<String> images = new ArrayList<>();
        List<MultipartFile> files = movementDto.getFiles();
        List<String> match = new ArrayList<>();
        match.add("png");
        match.add("jpg");
        match.add("jpeg");
        match.add("bmp");
        for (MultipartFile multipartFile : files) {

            if (ObjectUtil.isEmpty(multipartFile)) {
                continue;
            }
            String contentType = multipartFile.getContentType();
            if (StringUtils.isEmpty(contentType)) {
                continue;
            }
            String type = contentType.split("/")[1];
            if (!match.contains(type)) {
                continue;
            }
            String filename = new SimpleDateFormat("yyyy/MM/dd").format(new Date())
                    + "/" + UUID.randomUUID().toString() + "." + type;
            String url = "https://tanhuaservicebucket.oss-cn-hangzhou.aliyuncs.com";
            UploadDto uploadDto = new UploadDto();
            uploadDto.setFileName(filename);
            uploadDto.setUrl(url);
            uploadDto.setSource(Base64Util.inputStream2Base64(multipartFile.getInputStream()));
            rabbitTemplate.convertAndSend("ossexchage.direct", "osskey", JSON.toJSONString(uploadDto));
            images.add(url + "/" + filename);
        }
        String newImages = JSON.toJSONString(images);
        movement.setImages(newImages);
        movement.setUserId(ThreadLocalUtil.getId());
        movement.setId(IdUtil.getSnowflakeNextIdStr());
        movement.setCreateTime(LocalDateTime.now());
        movement.setUpdateTime(LocalDateTime.now());
        Boolean insert = movementMapper.insertMovement(movement);
        return insert;
    }

    @Override
    public PagingQueryVo<MovementVo> selectAllMovement(Integer type, Integer page, Integer pageSize) {
        Integer start = (page - 1) * pageSize;
        List<Movement> movements;
        if (type == 0) {
            movements = movementMapper.selectAllPage(null, start, pageSize);
        } else if (type == 1) {
            movements = movementMapper.selectAllPage(ThreadLocalUtil.getId(), start, pageSize);
        }else {
            throw new RuntimeException("类型错误");
        }
        if (CollectionUtils.isEmpty(movements)){
            return null;
        }
        List<MovementVo> movementVos = BeanUtil.copyToList(movements, MovementVo.class);
        //获取对应的用户信息
        Set<String> userIds = movements.stream().filter(Objects::nonNull).map(Movement::getUserId).collect(Collectors.toSet());

        List<String> userIdList = new ArrayList<>(userIds);
        UserClientDto userClientDto = new UserClientDto();
        userClientDto.setIds(userIdList);
        Object data = userClient.selectUsersByIds(userClientDto).getData();
        if (ObjectUtil.isEmpty(data)){
            throw new RuntimeException("用户数据异常");
        }
        String s = JSON.toJSONString(data);
        List<UserVo> userVos = JSONArray.parseArray(s).toList(UserVo.class);
        Map<String, List<UserVo>> userVosMap = userVos.stream().collect(Collectors.groupingBy(UserVo::getId));

        //获取喜欢和评论的信息
        Set<String> movementIds = movements.stream().filter(Objects::nonNull).map(Movement::getId).collect(Collectors.toSet());
        ArrayList<String> movementIdList = new ArrayList<>(movementIds);
        List<MovementLike> movementLikes = movementLikeService.selectByMovementIds(movementIdList);
        //动态点赞列表
        Map<String, List<MovementLike>> movementLikesMap = movementLikes.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(MovementLike::getMovementId));

        List<MovementCommentVo> movementComments = movementCommentService.selectByMovementIds(movementIdList);
        //动态评论列表
        Map<String, List<MovementCommentVo>> movementCommentsMap = movementComments.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(MovementCommentVo::getMovementId));
        for (MovementVo movementVo : movementVos) {
            UserVo userVo = userVosMap.get(movementVo.getUserId()).get(0);
            movementVo.setName(userVo.getName());
            movementVo.setGender(userVo.getGender());
            movementVo.setBirthday(userVo.getBirthday());
            movementVo.setCity(userVo.getCity());
            movementVo.setEducation(userVo.getEducation());
            movementVo.setHeadPortrait(userVo.getHeadPortrait());
            movementVo.setMarital(userVo.getMarital());

            movementVo.setTime(TimeUtil.handleTime(movementVo.getCreateTime()));

            int likeCount=0;
            if (!CollectionUtils.isEmpty(movementLikesMap)){
                List<MovementLike> movementLikes1 = movementLikesMap.get(movementVo.getId());
                if (!CollectionUtils.isEmpty(movementLikes1)){
                    likeCount=movementLikes1.size();
                }
            }
            movementVo.setLikeCount(likeCount);


            int commentCount=0;
            if (!CollectionUtils.isEmpty(movementCommentsMap)){
                List<MovementCommentVo> movementCommentVos = movementCommentsMap.get(movementVo.getId());
                if (!CollectionUtils.isEmpty(movementCommentVos)){
                    commentCount=movementCommentVos.size();
                }
            }
            movementVo.setCommentCount(commentCount);

            int commentLikeCount=0;
            if (!CollectionUtils.isEmpty(movementCommentsMap)){
                List<MovementCommentVo> movementCommentVos = movementCommentsMap.get(movementVo.getId());
                if (!CollectionUtils.isEmpty(movementCommentVos)){
                    for (MovementCommentVo movementCommentVo : movementCommentVos) {
                        List<MovementCommentLikeVo> likes = movementCommentVo.getLikes();
                        if (!CollectionUtils.isEmpty(likes)){
                            commentLikeCount+=likes.size();
                        }
                    }
                }
            }
            movementVo.setCommentLikeCount(commentLikeCount);
        }
        Integer total = movementMapper.countPage();
        PagingQueryVo<MovementVo> PagingQueryVo = new PagingQueryVo<>();
        PagingQueryVo.setData(movementVos);
        PagingQueryVo.setPage(page);
        PagingQueryVo.setTotal(total);
        PagingQueryVo.setPageSize(pageSize);
        PagingQueryVo.setPages(total / pageSize + 1);
        return PagingQueryVo;
    }

    @Override
    public Boolean deleteMovement(String id) {
        Movement movement = new Movement();
        movement.setId(id);
        movement.setIsDeleted(LocalDateTime.now());
        return movementMapper.updateMovementById(movement);
    }

    @Override
    public Boolean updateMovement(MovementDto movementDto) {
        Movement movement = new Movement();
        BeanUtils.copyProperties(movementDto,movement);
        movement.setUpdateTime(LocalDateTime.now());
        return movementMapper.updateMovementById(movement);
    }
}
